package launcher;

import scripts.Consolidacion;
import scripts.Creador;
import scripts.GeneraPaquete;
import scripts.GeneraPaqueteCompleto;
import scripts.ListadoFicheros;
import scripts.RemoteCommands;
import scripts.SincronizaFicheros;
import strings.Messages;
import ui.Display;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import common.Connection;
import common.Constants;
import common.LocalUtil;
import common.PropertiesManager;

public class Launcher {

	public static void main(String[] args) {
		// PropertiesManager.checkProperties();
		new Launcher(new OptionManager(args));
	}

	public Launcher(OptionManager om) {

		int error = om.checkArgs();
		if (error != OptionManager.OK) {
			switch (error) {
			case OptionManager.NO_ARGS:
			case OptionManager.NO_MODE:
				JOptionPane.showMessageDialog(null, Messages.getString("Launcher.0")); //$NON-NLS-1$
				return;
			case OptionManager.RCMODE_NOARGS:
			case OptionManager.RCMODE_NORCDIR:
				JOptionPane.showMessageDialog(null, Messages.getString("Launcher.1")); //$NON-NLS-1$
				return;
			case OptionManager.NORCMODE_NOARGS:
			case OptionManager.NORCMODE_NOCOMMANDS:
				JOptionPane.showMessageDialog(null, Messages.getString("Launcher.2")); //$NON-NLS-1$
				return;
			case OptionManager.PACKAGEMODE_NOARGS:
			case OptionManager.PACKAGEMODE_NOPACKAGEDIR:
				JOptionPane.showMessageDialog(null, Messages.getString("Launcher.3")); //$NON-NLS-1$
				return;
			case OptionManager.COMMON_NO_PROPERTIES_FILE:
				JOptionPane.showMessageDialog(null, Messages.getString("Launcher.10")); //$NON-NLS-1$
				return;
			}
		}

		PropertiesManager.setPropertiesFilePath(om.getPropertiesFile());

		Script script = createScript(om);
		if (script != null) {
			Display.debug("Instanciando script '" + script.getName() + "' ...");
			script.start();

			try {
				script.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		// System.exit(0);
	}

	private Script createScript(OptionManager om) {

		switch (om.getMode()) {

		case OptionManager.OP_CREATE:
			return new Creador();
		case OptionManager.OP_LIST:
		case OptionManager.OP_COPY:
		case OptionManager.OP_SINC:
			return createRCScript(new Display(), om);
		case OptionManager.OP_RL:
			return new RemoteCommands(new Display(), new Connection(om.getEnvironment()), om.getRemoteLauncherCommand());
		case OptionManager.OP_PACKAGE:
			return new GeneraPaqueteCompleto(om.getPackageDir());
		case OptionManager.OP_CONSOLIDATE:
			return new Consolidacion(new Display(), new Connection(om.getEnvironment()), om.getPackageDir());
		default:
			return null;
		}
	}

	private Script createRCScript(Display display, OptionManager om) {
		String directorioIncidendia = om.getRcDir();

		File di = new File(directorioIncidendia);
		if (!di.exists() || !di.isDirectory() || !di.canWrite()) {
			System.out.printf(Messages.getString("Launcher.4"), directorioIncidendia); //$NON-NLS-1$
			return null;
		}

		try {
			directorioIncidendia = di.getCanonicalPath().replace("\\", "/") + "/"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		} catch (IOException e) {
			System.out.println(Messages.getString("Launcher.8")); //$NON-NLS-1$
			return null;
		}

		display.write(String.format(Messages.getString("Launcher.9"), directorioIncidendia)); //$NON-NLS-1$

		String prjFileName = LocalUtil.getProjectFileName(di);
		if (prjFileName == null) {
			System.out.println(Messages.getString("Launcher.10")); //$NON-NLS-1$
			return null;
		}

		if (om.getMode() == OptionManager.OP_LIST) {
			String lofn = PropertiesManager.getProperty("Local", "ListOutputFilename"); //$NON-NLS-1$ //$NON-NLS-2$
			return new ListadoFicheros(display, directorioIncidendia + prjFileName, directorioIncidendia + Constants.DOCDIR_NAME, lofn);
		}
		if (om.getMode() == OptionManager.OP_COPY)
			return new GeneraPaquete(directorioIncidendia + prjFileName, directorioIncidendia + Constants.IMPDIR_NAME);
		if (om.getMode() == OptionManager.OP_SINC)
			return new SincronizaFicheros(display, new Connection(om.getEnvironment()), directorioIncidendia + prjFileName, directorioIncidendia
					+ Constants.IMPDIR_NAME, directorioIncidendia + "Scripts/" + Constants.SELECTED_FILES_NAME); //$NON-NLS-1$
		return null;
	}
}

class OptionManager {

	public String[] args = null;

	private int mode;
	private String rcDir;
	private String environment;
	private String packageDir;
	private List<String> remoteLauncherCommands;

	private String filePropertiesPath;

	public static final int OK = 0;
	public static final int NO_ARGS = 1;
	public static final int NO_MODE = 2;
	public static final int RCMODE_NOARGS = 3;
	public static final int RCMODE_NORCDIR = 4;
	public static final int NORCMODE_NOARGS = 5;
	public static final int NORCMODE_NOCOMMANDS = 6;
	public static final int PACKAGEMODE_NOARGS = 7;
	public static final int PACKAGEMODE_NOPACKAGEDIR = 8;
	public static final int COMMON_NO_PROPERTIES_FILE = 9;

	public static final int OP_CREATE = 1;
	public static final int OP_SINC = 2;
	public static final int OP_COPY = 3;
	public static final int OP_LIST = 4;
	public static final int OP_RL = 5;
	public static final int OP_PACKAGE = 6;
	public static final int OP_CONSOLIDATE = 7;

	public OptionManager(String[] args) {
		this.args = args;
	}

	public int checkArgs() {
		if (args.length == 0) {
			return NO_ARGS;
		}

		// First arg always must be the run mode
		if (args[0].equals("-create")) { //$NON-NLS-1$
			mode = OP_CREATE;
			return checkPropertiesArgs();
		} else if (args[0].equals("-sinc")) { //$NON-NLS-1$
			mode = OP_SINC;
			return checkRCArgs();
		} else if (args[0].equals("-copy")) { //$NON-NLS-1$
			mode = OP_COPY;
			return checkRCArgs();
		} else if (args[0].equals("-list")) { //$NON-NLS-1$
			mode = OP_LIST;
			return checkRCArgs();
		} else if (args[0].equals("-rl")) { //$NON-NLS-1$
			mode = OP_RL;
			return checkNoRCArgs();
		} else if (args[0].equals("-pack")) { //$NON-NLS-1$
			mode = OP_PACKAGE;
			return checkPackageArgs();
		} else if (args[0].equals("-cons")) { //$NON-NLS-1$
			mode = OP_CONSOLIDATE;
			return checkConsolidateArgs();
		} else {
			return NO_MODE;
		}
	}

	private int checkPropertiesArgs() {
		if (args.length <= 1) {
			return RCMODE_NOARGS;
		}

		for (int i = 1; i < args.length; i++) {
			if (args[i].equals("-p") && (i + 1 < args.length)) //$NON-NLS-1$
				filePropertiesPath = args[i + 1];
		}

		if (filePropertiesPath == null)
			return COMMON_NO_PROPERTIES_FILE;

		return OK;
	}

	private int checkRCArgs() {
		if (args.length <= 1) {
			return RCMODE_NOARGS;
		}

		for (int i = 1; i < args.length; i++) {
			if (args[i].equals("-d") && (i + 1 < args.length)) //$NON-NLS-1$
				rcDir = args[i + 1];
			if (args[i].equals("-e") && (i + 1 < args.length)) //$NON-NLS-1$
				environment = args[i + 1];
		}

		if (rcDir == null)
			return RCMODE_NORCDIR;

		return checkPropertiesArgs();
	}

	private int checkNoRCArgs() {
		if (args.length <= 1) {
			return NORCMODE_NOARGS;
		}

		remoteLauncherCommands = new ArrayList<String>();

		for (int i = 1; i < args.length; i++) {
			if (args[i].equals("-chu") || args[i].equals("-chb") || args[i].equals("-iu") || args[i].equals("-ib") || args[i].equals("-cucust") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
					|| args[i].equals("-cucore")) //$NON-NLS-1$
				remoteLauncherCommands.add(args[i].substring(1));
			if (args[i].equals("-e") && (i + 1 < args.length)) //$NON-NLS-1$
				environment = args[i + 1];
		}

		if (remoteLauncherCommands.isEmpty())
			return NORCMODE_NOCOMMANDS;

		return checkPropertiesArgs();
	}

	private int checkPackageArgs() {
		if (args.length <= 1) {
			return PACKAGEMODE_NOARGS;
		}

		for (int i = 1; i < args.length; i++) {
			if (args[i].equals("-dp")) //$NON-NLS-1$
				packageDir = args[i + 1];
		}

		/*
		 * if (packageDir == null) return PACKAGEMODE_NOPACKAGEDIR;
		 */

		return checkPropertiesArgs();
	}

	private int checkConsolidateArgs() {
		if (args.length <= 1) {
			return PACKAGEMODE_NOARGS;
		}

		for (int i = 1; i < args.length; i++) {
			if (args[i].equals("-dp")) //$NON-NLS-1$
				packageDir = args[i + 1];
			if (args[i].equals("-e") && (i + 1 < args.length)) //$NON-NLS-1$
				environment = args[i + 1];
		}

		return checkPropertiesArgs();
	}

	public int getMode() {
		return mode;
	}

	public String getRcDir() {
		return rcDir;
	}

	public String getEnvironment() {
		if (environment == null)
			environment = "Mant"; //$NON-NLS-1$
		return environment;
	}

	public String getPackageDir() {
		return packageDir;
	}

	public List<String> getRemoteLauncherCommand() {
		return remoteLauncherCommands;
	}

	public String getPropertiesFile() {
		return filePropertiesPath;
	}
}